/*
 * Copyright 2001 Alexander Boverman and the original authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _WT_CONTEXT_H
#define _WT_CONTEXT_H

#include "WtSession.h"
#include "apreq.h"

typedef enum {
  WT_STATUS_NONE,
  WT_STATUS_OK,
  WT_STATUS_ERROR,
  WT_STATUS_FATAL
} WtStatus;

/* Initial request state */

typedef struct WtDispatchT
{
  Tcl_Time startTime;
  int status;
  int terminate;
} WtDispatch;

typedef struct WtPageLoaderT
{
  Tcl_Obj *includeSearchPath;
  Tcl_Obj *includeNamespace;
  int addHeaderTrailer;
  Tcl_Obj *includeHeader;
  Tcl_Obj *includeTrailer;
  Tcl_Obj *scriptStartString;
  Tcl_Obj *scriptEndString;
  int interpolateText;
  Tcl_Obj *textHandler;
  Tcl_Obj *exprHandler;
  int pageIndex;
  Tcl_Obj *pageStack;
} WtPageLoader;

typedef struct WtClientRequestT
{
  Tcl_Obj *headers;
  int parseStatus;
  int readRequestStatus;
  ApacheRequest *apWeb;
  Tcl_Obj *queryParams;
  Tcl_Obj *postParams;
  int readCookiesStatus;
  ApacheCookieJar *apCookies;
  Tcl_Obj *cookies;
  Tcl_Obj *uploads;
  Tcl_Obj *uploadHandler;
  Tcl_Obj *uploadHandlerData;
  Tcl_Obj *params;
} WtClientRequest;

typedef struct WtClientResponseT
{
  Tcl_Obj *contentType;
  Tcl_Obj *headers;
  Tcl_Obj *successHeaders;
  WtStatus headersStatus;
  Tcl_Obj *cookies;
  int status;
} WtClientResponse;

typedef struct WtWebContextT
{
  int isPersistent;
  request_rec *apReq;
  int ctxRequestCount;
  Tcl_Time requestStartTime;
  int aInitDone;
  int interpRequestCount;
  int errorState;
  Tcl_Obj *notices;
  Tcl_Obj *taskSettings;
  int interpIsNew;
  Tcl_Interp *interp;
  time_t interpCreationTime;
  int packageLoadDone;
  Tcl_Obj *usedNamespaces;
  Tcl_Obj *taskNamespace;
  Tcl_Obj *ctxEventHandlers;
  int bInitDone;
  int importCommands;
  int pageIsStarted;
  int readEnvStatus;
  Tcl_Obj *serverVars;
  WtPageLoader loader;
  WtClientRequest clientRequest;
  WtClientResponse clientResponse;
  Tcl_Obj *errorStack;
  int deleteInterp;
  int terminate;
  WtSession session;
  Tcl_Obj *dataSourceHandler;
} WtWebContext;

typedef struct WtContextT
{
  int debug;
  server_rec *apServer;
  request_rec *apReq;
  int requestCount;
  Tcl_Channel webChannel;
  Tcl_HashTable *optionCodes;
  Tcl_HashTable *optionKeys;
  Tcl_Obj *defaultCtxSettings;
  WtWebContext *persistentWebContext;
  WtWebContext *transientWebContext;
  WtWebContext *web;
} WtContext;

typedef struct WtThreadStorageT
{
  WtContext *context;
} WtThreadStorage;

void WtInitServer(server_rec *s, pool *p);
WtContext *WtGetContext();
int WtProcessRequest(request_rec *r);
int WtInitRequest(WtContext *w, request_rec *r, WtDispatch *disp);
int WtInitWebContext(WtContext *w, int initRequest);
WtWebContext *WtCreateWebContext(int isPersistent);
int WtCreateInterp(WtContext *w, int initRequest);
int WtInitInterp(WtContext *w, int initRequest);
int WtInitPackages(WtContext *w, int initRequest);
int WtInitTaskObjectsB(WtContext *w);
int WtEndRequest(WtContext *w, request_rec *r, WtDispatch *disp);
int WtRecreateInterp(WtContext *w, WtDispatch *disp);
int WtDeleteInterp(WtContext *w);
int WtReuseInterp(WtContext *w);
int WtClearTaskObjects(WtContext *w);
int WtDeleteContext();
int WtDeleteWebContext(WtContext *w);
void WtEndServer(server_rec *s, pool *p);
Tcl_Obj *WtGetServerConf(server_rec *s);
Tcl_Obj *WtGetDirConf(request_rec *r);
WtContext *WtGetAssocContext(Tcl_Interp *interp);

extern const char *wtVersion;

#endif /* !_WT_CONTEXT_H */
